<template>
  <div class="app-container">
    <div class="search-container">
      <el-form :model="searchParam" :inline="true">
        <el-form-item label="角色名称">
          <el-input
            v-model="searchParam.roleName"
            placeholder="请输入角色名称"
            clearable
            @keyup.enter="search"
          />
        </el-form-item>
        <el-form-item label="读取列表">
          <el-select v-model="searchParam.type" placeholder="Select">
            <el-option
              v-for="item in useDictionary('LogLevel')"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="组织机构选择">
          <SelectOriganization
            @change="getSelectIds"
            @change-data="getSelectDatas"
            :isCheckStrictly="true"
            :isMultiple="false"
            :disabled="true"
            selectData="1156f1fdf86a4e33b68cfbadd1ee04a4"
          />
        </el-form-item>
        <!-- <el-form-item label="人员选择">
          <el-select
            ref="selectRef"
            v-model="personSelectOptions"
            multiple
            placeholder="请选择人员"
            :collapse-tags="true"
            :collapse-tags-tooltip="true"
            :max-collapse-tags="5"
            style="width: 400px"
            @visible-change="openSelectOriganization"
            @remove-tag="removeSelection"
          >
            <el-option
              v-for="item in personOptions"
              :key="item.id"
              :label="item.firstName"
              :value="item.id"
            />
          </el-select>
        </el-form-item> -->

        <!-- 地区选择器 -->
        <el-form-item label="地区选择器">
          <el-cascader
            :options="areaOptions"
            v-model="selectedOptions"
            clearable
            @change="areaHandleChange"
          />
        </el-form-item>

        <el-form-item label="简约人员选择">
          <SelectPerson
            :maxCollapseTags="5"
            :isMultiple="false"
            :width="`100%`"
            :showSelectPerson="selectPersonData"
            @get-person="getPerson"
          />
        </el-form-item>

        <span v-show="!collapsed">
          <el-form-item label="角色名称">
            <el-input
              v-model="searchParam.roleName"
              placeholder="请输入角色名称"
              clearable
              @keyup.enter="search"
            />
          </el-form-item>
          <el-form-item label="角色名称">
            <el-input
              v-model="searchParam.roleName"
              placeholder="请输入角色名称"
              clearable
              @keyup.enter="search"
            />
          </el-form-item>
          <el-form-item label="角色名称">
            <el-input
              v-model="searchParam.roleName"
              placeholder="请输入角色名称"
              clearable
              @keyup.enter="search"
            />
          </el-form-item>
          <el-form-item label="角色名称">
            <el-input
              v-model="searchParam.roleName"
              placeholder="请输入角色名称"
              clearable
              @keyup.enter="search"
            />
          </el-form-item>
          <el-form-item label="角色名称">
            <el-input
              v-model="searchParam.roleName"
              placeholder="请输入角色名称"
              clearable
              @keyup.enter="search"
            />
          </el-form-item>
        </span>
        <!-- 组织机构选择插件使用 -->
        <el-form-item>
          <el-button type="primary" @click="search">
            <i-ep-search />
            搜索
          </el-button>
          <el-button @click="reset">
            <i-ep-refresh />
            重置
          </el-button>
          <el-button type="primary" link @click="collapsed = !collapsed">
            {{ collapsed ? "展开" : "收起" }}
            <i-ep-arrowUp v-if="!collapsed" class="ml-[3px]" />
            <i-ep-arrowDown v-else class="ml-[3px]" />
          </el-button>
        </el-form-item>
      </el-form>
    </div>

    <el-card shadow="never" class="table-container">
      <template #header>
        <el-button type="success" plain @click="openDialog()">
          <i-ep-plus />
          新增
        </el-button>
        <el-button
          type="danger"
          plain
          :disabled="ids.length === 0"
          @click="handleTableDelete()"
        >
          <i-ep-delete />
          删除
        </el-button>
        <el-button
          class="ml-3"
          @click="
            useDownload('/system/sysRole/export', '导出表格名称', searchParam)
          "
          ><template #icon><i-ep-download /></template>导出</el-button
        >
        <el-button
          v-if="showToolButton('setting') && columns.length"
          circle
          @click="openColSetting"
        />
      </template>

      <!-- <el-table
        ref="dataTableRef"
        v-loading="loading"
        :data="tableData"
        highlight-current-row
        border
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="角色ID" prop="id" min-width="100" />
        <el-table-column label="角色名称" prop="roleName" min-width="100" />
        <el-table-column label="备注" prop="remarks" width="150" />

        <el-table-column label="状态" align="center" width="100">
          <template #default="scope">
            <el-tag>
              {{ useDictionary("Enabled", scope.row.enabled) }}
            </el-tag>
          </template>
        </el-table-column>

        <el-table-column fixed="right" label="操作" width="240">
          <template #default="scope">
            <el-button
              type="primary"
              size="small"
              link
              @click="openDialog(scope.row)"
            >
              <i-ep-edit />
              编辑
            </el-button>
            <el-button
              type="primary"
              size="small"
              link
              @click="handleTableDelete(scope.row.id)"
            >
              <i-ep-delete />
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table> -->

      <!-- 表格主体 -->
      <el-table
        ref="dataTableRef"
        v-loading="loading"
        v-bind="$attrs"
        :data="tableData"
        highlight-current-row
        border
        @selection-change="handleSelectionChange"
      >
        <!-- 默认插槽 -->
        <slot></slot>
        <template v-for="item in tableColumns" :key="item">
          <!-- selection || radio || index || expand || sort -->
          <el-table-column
            v-if="item.type && columnTypes.includes(item.type)"
            v-bind="item"
            :align="item?.align ?? 'center'"
            :reserve-selection="item.type == 'selection'"
          >
            <template #default="scope">
              <!-- expand -->
              <!-- <template v-if="item.type == 'expand'">
                <component
                  :is="item.render"
                  v-bind="scope"
                  v-if="item.render"
                />
                <slot v-else :name="item.type" v-bind="scope"></slot>
              </template> -->
              <!-- radio -->
              <!-- <el-radio
                v-if="item.type == 'radio'"
                v-model="radio"
                :label="scope.row[rowKey]"
              >
                <i></i>
              </el-radio> -->
              <!-- sort -->
              <!-- <el-tag v-if="item.type == 'sort'" class="move">
                <el-icon> <DCaret /></el-icon>
              </el-tag> -->
            </template>
          </el-table-column>
          <!-- other -->
          <TableColumn
            v-if="!item.type && item.prop && item.isShow"
            :column="item"
          >
            <template v-for="slot in Object.keys($slots)" #[slot]="scope">
              <slot :name="slot" v-bind="scope"></slot>
            </template>
          </TableColumn>
        </template>
        <!-- 插入表格最后一行之后的插槽 -->
        <template #append>
          <slot name="append"></slot>
        </template>
        <!-- 无数据 -->
        <template #empty>
          <div class="table-empty">
            <div>暂无数据</div>
            <!-- <slot name="empty">
              <img src="@/assets/images/notData.png" alt="notData" />
              <div>暂无数据</div>
            </slot> -->
          </div>
        </template>
      </el-table>

      <el-pagination
        :background="true"
        :current-page="pageable.pageNum"
        :page-size="pageable.pageSize"
        :page-sizes="[10, 25, 50, 100]"
        :total="pageable.total"
        layout="total, sizes, prev, pager, next, jumper"
        class="mt-[20px]"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-card>

    <add-table
      :visible="addDialog.visible"
      :title="addDialog.title"
      :data="addDialog.data"
      @reset-table="reset"
      @change-visible="changeVisible"
    />

    <!-- <SelectPersonDialog
      v-model:visible="personSelect.visible"
      :data="personSelect.data"
      @echo-info="getPersonSelect"
    /> -->
    <!-- 列设置 -->
    <ColSetting
      v-if="toolButton"
      ref="colRef"
      v-model:col-setting="colSetting"
    />
  </div>
</template>

<script setup lang="ts">
import { useTable, useDownload, useDictionary } from "@/utils/useTable";
import { ElSelect } from "element-plus";
import { BreakPoint } from "@/components/Grid/interface";
import { regionData, codeToText } from "element-china-area-data";
defineOptions({
  name: "SYSTEMTABLE",
  inheritAttrs: false,
});

// 需要联动的数据
const areaOptions = ref(regionData);
// 需要回显的数据
const selectedOptions = ref(["12", "1201", "120101"]);
// 变更事件
function areaHandleChange(value: any) {
  if (value) {
    // 赋值操作
    console.log("code", value);
    console.log(
      "中文",
      codeToText[value[0]],
      codeToText[value[1]],
      codeToText[value[2]]
    );
  } else {
    // 清空和重置操作
  }
}

/** 列表项自定义方法   start **/
// column 列类型
const columnTypes: string[] = ["selection", "radio", "index", "expand", "sort"];
// 定义操作按钮
const toolButton = reactive(["refresh", "setting"]);
// 控制 ToolButton 显示
const showToolButton = (key: "refresh" | "setting" | "search") => {
  return Array.isArray(toolButton) ? toolButton.includes(key) : toolButton;
};

const radio = ref();
// 表格配置项
const columns = reactive([
  { type: "radio", label: "单选", width: 80 },
  { type: "index", label: "#", width: 80 },
  { prop: "id", label: "角色ID", width: 100 },
  { prop: "roleName", label: "角色名称", width: 100 },
  { prop: "remarks", label: "备注", width: 150 },
  {
    prop: "enabled",
    label: "状态",
    width: 120,
    sortable: true,
    enum: useDictionary("Enabled"),
  },
  { prop: "operation", label: "操作", width: 330, fixed: "right" },
]);
// 接收 columns 并设置为响应式
const tableColumns = reactive([
  { type: "radio", label: "单选", width: 80, isShow: true },
  { type: "index", label: "#", width: 80, isShow: true },
  { prop: "id", label: "角色ID", width: 100, isShow: true },
  { prop: "roleName", label: "角色名称", width: 100, isShow: true },
  { prop: "remarks", label: "备注", width: 150, isShow: true },
  {
    prop: "enabled",
    label: "状态",
    width: 120,
    sortable: true,
    isShow: true,
    enum: useDictionary("Enabled"),
  },
  {
    prop: "operation",
    label: "操作",
    isShow: true,
    width: 330,
    fixed: "right",
  },
]);

watchEffect(() => {
  console.log("数据被修改了", tableColumns); // 控制台可以看到double数据变化了（通过double.value）。
});

// 扁平化 columns
const flatColumns = computed(() => flatColumnsFunc(tableColumns));

// 定义 enumMap 存储 enum 值（避免异步请求无法格式化单元格内容 || 无法填充搜索下拉选择）
const enumMap = ref(new Map<string, { [key: string]: any }[]>());
const setEnumMap = async ({ prop, enum: enumValue }: any) => {
  if (!enumValue) return;

  // 如果当前 enumMap 存在相同的值 return
  if (
    enumMap.value.has(prop!) &&
    (typeof enumValue === "function" || enumMap.value.get(prop!) === enumValue)
  )
    return;

  // 当前 enum 为静态数据，则直接存储到 enumMap
  if (typeof enumValue !== "function")
    return enumMap.value.set(prop!, unref(enumValue!));

  // 为了防止接口执行慢，而存储慢，导致重复请求，所以预先存储为[]，接口返回后再二次存储
  enumMap.value.set(prop!, []);

  // 当前 enum 为后台数据需要请求数据，则调用该请求接口，并存储到 enumMap
  const { data } = await enumValue();
  enumMap.value.set(prop!, data);
};

// 注入 enumMap
provide("enumMap", enumMap);

// 扁平化 columns 的方法
const flatColumnsFunc = (columns: any[], flatArr: any[] = []) => {
  columns.forEach(async (col) => {
    if (col._children?.length) flatArr.push(...flatColumnsFunc(col._children));
    flatArr.push(col);

    // column 添加默认 isShow && isFilterEnum 属性值
    col.isShow = col.isShow ?? true;
    col.isFilterEnum = col.isFilterEnum ?? true;

    // 设置 enumMap
    await setEnumMap(col);
  });
  return flatArr.filter((item) => !item._children?.length);
};

// 列设置 ==> 需要过滤掉不需要设置的列
const colRef = ref();
const colSetting = tableColumns!.filter((item) => {
  const { type, prop, isShow } = item;
  return !columnTypes.includes(type!) && prop !== "operation" && isShow;
});
const openColSetting = () => colRef.value.openColSetting();
/** 列表项自定义方法   end **/

// 是否默认折叠搜索项
const collapsed = ref(true);
// 获取响应式断点
const gridRef = ref();
const breakPoint = computed<BreakPoint>(() => gridRef.value?.breakPoint);
// 获取响应式设置
const getResponsive = (item: any) => {
  return {
    span: item.search?.span,
    offset: item.search?.offset ?? 0,
    xs: item.search?.xs,
    sm: item.search?.sm,
    md: item.search?.md,
    lg: item.search?.lg,
    xl: item.search?.xl,
  };
};

/** 打开组织机构选择器方法   start **/
function getSelectIds(ids: [] | string) {
  console.log("所选组织机构ids", ids);
}
function getSelectDatas(datas: [] | {}) {
  console.log("所选组织机构Datas", datas);
}
/** 打开组织机构选择器方法   end **/

/** new 打开人员选择器方法   start **/
const selectPersonData = ref([
  {
    id: "1727561827892842497",
    firstName: "sdf",
  },
]);
function getPerson(Ids: string[], Objects: any) {
  console.log("人员选择变化啦", Ids, Objects);
}
/** new 打开人员选择器方法   start **/

/** 打开人员选择器方法   start **/
interface SelectOption {
  id?: string;
}
const personSelectOptions: any = ref([]); // 选择器 list
const personOptions: any = ref([]); // 选择器 model
const selectRef = ref(ElSelect); // 选择器 ref
// 定义 人员选择器弹窗参数
const personSelect = reactive<DialogOption>({
  visible: false,
  data: [],
});
// 移除 人员tag标签
function removeSelection(id: SelectOption) {
  personOptions.value.forEach((row: SelectOption, index: number) => {
    if (row.id === id) personOptions.value.splice(index, 1);
  });
}
// 打开 人员选择器弹窗
function openSelectOriganization(event: boolean) {
  if (event) {
    selectRef.value.blur(); // 隐藏下拉框
    personSelect.visible = true;
    personSelect.data = personOptions.value;
  }
}
// 接收 人员选择器回调参数
function getPersonSelect(options: any) {
  personOptions.value = options;
  const ids: any = [];
  options?.map((item: SelectOption) => ids.push(item.id));
  personSelectOptions.value = ids || [];
}

/** 打开人员选择器方法   end **/

// 请求参数
const requestApi = "/system/sysRole/queryByPage";

// 是否需要分页
const pagination = true;

const initParam = {};

// 初始化搜索参数数据
const searchParamInit = {
  roleName: "",
};

const deleteParam = {
  api: "/system/sysRole/delete",
  data: {},
};

// 如果初始化表格需要排序=》const initParam = reactive({sort:''});
// 监听页面 initParam 改化，重新获取表格数据
// watch(() => initParam, getTableList, { deep: true });

// 数据请求错误后处理
function requestError() {}

// 数据请求错误后处理
// function dataCallBack() {}   //需要处理
const dataCallBack = ref(undefined); //无需二次数据处理&不传赞数也行

// 表格操作 Hooks
const {
  tableData,
  pageable,
  searchParam,
  ids,
  getTableList,
  search,
  reset,
  handleSizeChange,
  handleCurrentChange,
  handleSelectionChange,
  handleTableDelete,
  loading,
}: any = useTable(
  requestApi,
  initParam,
  searchParamInit,
  pagination,
  dataCallBack.value,
  requestError,
  deleteParam
);

onMounted(async () => {
  getTableList();
});

/** 打开角色表单弹窗 */
const addDialog = reactive<DialogOption>({
  visible: false,
  title: "",
  data: {},
});

const classData = {
  id: "jeffjeffjeffjeffjeffjeff",
  className: "hahaha",
  classPerson: "asdcasd",
  classTeacher: "jeff",
  classId: "jeffjeff",
  studentData: [
    {
      id: "111",
      sex: "1",
      name: "haha",
      isLive: false,
      phone: "17600002036",
    },
    {
      id: "222",
      sex: "2",
      name: "haha8989",
      isLive: true,
      phone: "17600602036",
    },
  ],
};

function openDialog(roleObj?: Object) {
  addDialog.visible = true;
  if (roleObj) {
    addDialog.title = "修改角色";
    addDialog.data = classData;
    console.log("修改角色", addDialog.data);
  } else {
    addDialog.title = "新增角色";
  }
}

function changeVisible(value: boolean) {
  addDialog.visible = value;
}

/** 分配权限 */
function openMenuDialog() {}
</script>
